<template>
  <view :style="[flexStyle]" class="sc-flex" @tap="tapHandler">
    <slot></slot>
  </view>
</template>

<script>
import { backgroundProps, backgroundStyle } from "../../libs/props/background.js";
import { marginProps, marginStyle } from "../../libs/props/margin.js";
import { paddingProps, paddingStyle } from "../../libs/props/padding.js";
import { positionProps, positionStyle } from "../../libs/props/position.js";
import mpMixin from "../../libs/mixin/mpMixin.js";
import mixin from "../../libs/mixin/mixin.js";

const DIRECTION_MAP = {
  l: "row",
  r: "row-reverse",
  t: "column",
  b: "column-reverse"
};

const WRAP_MAP = {
  wrap: "wrap",
  reverse: "wrap-reverse",
  nowrap: "nowrap"
};

const JUSTIFY_CONTENT_MAP = {
  start: "flex-start",
  end: "flex-end",
  center: "center",
  between: "space-between",
  around: "space-around",
  evenly: "space-evenly",
  baseline: "baseline",
  "first-baseline": "first baseline",
  "last-baseline": "last baseline",
  "safe-center": "safe center"
};

const ALIGN_ITEMS_MAP = {
  start: "flex-start",
  end: "flex-end",
  center: "center",
  baseline: "baseline",
  stretch: "stretch",
  "first-baseline": "first baseline",
  "last-baseline": "last baseline",
  "safe-center": "safe center"
};

const ALIGN_CONTENT_MAP = {
  start: "flex-start",
  end: "flex-end",
  center: "center",
  between: "space-between",
  around: "space-around",
  stretch: "stretch"
};

const ALIGN_SELF_MAP = {
  start: "flex-start",
  end: "flex-end",
  center: "center",
  "self-start": "self-start",
  "self-end": "self-end",
  baseline: "baseline",
  "first-baseline": "first baseline",
  "last-baseline": "last baseline"
};

export default {
  name: "ScFlex",
  mixins: [mpMixin, mixin],
  props: {
    width: [String, Number],
    height: [String, Number],
    round: [String, Number],
    opacity: [Number, String],
    hidden: {
      type: Boolean,
      default: false
    },
    shadow: String,
    border: String,
    zIndex: [Number, String],
    direction: String,
    wrap: String,
    grow: [Number, String],
    shrink: [Number, String],
    basis: [Number, String],
    jc: String,
    ai: String,
    ac: String,
    as: String,
    gap: [String, Number],
    rowGap: {
      type: [String, Number],
      default: 0
    },
    colGap: {
      type: [String, Number],
      default: 0
    },
    customStyle: {
      type: Object,
      default: () => ({})
    },
    ...backgroundProps,
    ...marginProps,
    ...paddingProps,
    ...positionProps
  },
  emits: ['click'],
  data() {
    return {};
  },
  computed: {
    flexStyle() {
      const baseStyle = {
        width: this.width && this.$sc.addUnit(this.width),
        height: this.height && this.$sc.addUnit(this.height),
        borderRadius: this.round && this.$sc.addUnit(this.round),
        opacity: this.opacity,
        boxShadow: this.shadow,
        border: this.border,
        overflow: this.hidden ? "hidden" : undefined,
        zIndex: this.zIndex,
        flexDirection: this.direction && DIRECTION_MAP[this.direction],
        flexWrap: this.wrap && WRAP_MAP[this.wrap],
        justifyContent: this.jc && JUSTIFY_CONTENT_MAP[this.jc],
        alignItems: this.ai && ALIGN_ITEMS_MAP[this.ai],
        alignContent: this.ac && ALIGN_CONTENT_MAP[this.ac],
        alignSelf: this.as && ALIGN_SELF_MAP[this.as],
        flexGrow: this.grow,
        flexShrink: this.shrink,
        flexBasis: this.basis && this.$sc.addUnit(this.basis),
        gap:
          this.gap ||
          `${this.$sc.addUnit(this.rowGap)} ${this.$sc.addUnit(this.colGap)}`
      };

      // 合并其他样式
      return this.$sc.deepMerge(baseStyle, backgroundStyle(this), marginStyle(this), paddingStyle(this), positionStyle(this), this.customStyle);
    }
  },
  methods: {
    tapHandler() {
      this.$emit("click");
    },
  }
};
</script>

<style lang="scss" scoped>
.sc-flex {
  display: flex;
  box-sizing: border-box;
}
</style>
